/****************************************************************
 ** Product  :   HP Subscriber Network Application Policy
 ** Module   :   gr-manager
 ** Date: Apr 10, 2015               
 ** Author: Huang xiaoji
 ** (C) Copyright 2015, Hewlett-Packard Company, All Rights Reserved.
 ** This software is the proprietary information of HP, Inc.  
 ** Use is subject to license terms.
 *****************************************************************
 ** Description:   
 **    Generate status info for SGR.
 **    
 ****************************************************************/
package com.hp.snap.gr.action.impl;

import com.hp.snap.gr.exception.ActionException;
import com.hp.snap.gr.model.ReplicatorStatusInfo;
import com.hp.snap.gr.model.jaxb.ActionType;
import com.hp.snap.gr.model.jaxb.GeneralActionType;
import com.hp.snap.gr.model.jaxb.ParameterType;
import com.hp.snap.gr.utils.Constants;
import com.hp.snap.gr.utils.SSHTools;
import com.hp.snap.gr.utils.Utils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * Generate status info for SGR. Through by getting SGR.export*.zip files info to construct SGR info and save into
 * actionOuput object to pass it next action to handler. The status info encapsulate in a ReplicatorStatusInfo object
 * which contains some items: fileName, createdTime, fileSize.
 * 
 * There are two parameters can be configured in the action, packageFileDir and remotePackageFileDir. packageFileDir:
 * The package file folder. remotePackageFileDir: The package file folder in remote site.
 * 
 * 
 * <P>
 * Version: 3.3 <br>
 * Author: Huang xiaoji 
 * Date: Apr 10, 2015
 * 
 * </P>
 * 
 **/
public class GenerateReplicatorStatusInfoActionHandler extends AbstractActionHandler {
    public static final String PARAMETER_PACKAGE_FILE_DIR = "packageFileDir";
    public static final String PARAMETER_REMOTE_PACKAGE_FILE_DIR = "remotePackageFileDir";
    private static final Logger logger = LoggerFactory.getLogger(GenerateReplicatorStatusInfoActionHandler.class);
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void execute(ActionType action, Map<String, Object> actionPlanInputs, Map<String, Object> actionPlanOutputs) throws ActionException {
        if (action instanceof GeneralActionType) {
            GeneralActionType actionType = (GeneralActionType) action;
            String packageFileDir = null;
            String remotePackageFileDir = null;
            for (ParameterType p : actionType.getParameter()) {
                if (p.getName().equals(PARAMETER_PACKAGE_FILE_DIR)) {
                    packageFileDir = p.getVal();
                } else if (p.getName().equals(PARAMETER_REMOTE_PACKAGE_FILE_DIR)) {
                    remotePackageFileDir = p.getVal();
                }
            }
            if (StringUtils.isEmpty(packageFileDir)) {
                logger.error("action configuration missing parameters, packageFileDir: {}", packageFileDir);
                throw new ActionException("action configuration missing parameters");
            }
            File root = new File(packageFileDir);
            if (!root.exists()) {
//                logger.error("configured package file dir {} is not exists", root.getAbsolutePath());
//                throw new ActionException("package file dir is not exists");
            	if(!root.mkdirs()){
            		logger.error("configured package file dir {} create failed!", root.getAbsolutePath());
                    throw new ActionException("package file dir created failed");	
            	}
            }
            ReplicatorStatusInfo statusInfo = new ReplicatorStatusInfo();
            long f_last_update = 0;

            for (File file : root.listFiles()) {
                if (file.getName().startsWith("SGR.export.") && file.getName().endsWith(".zip")) {
                    if (file.lastModified() > f_last_update) {
                        f_last_update = file.lastModified();
                        statusInfo.setFileName(file.getAbsolutePath());
                        statusInfo.setFileSize(String.valueOf(file.length()));
                        statusInfo.setCreatedTime(DATE_FORMAT.format(new Date(file.lastModified())));
                    }
                }
            }
            if (f_last_update > 0) {
                actionPlanOutputs.put(Constants.REPLICATOR_STATUS_INFO, statusInfo);
            }

            if (remotePackageFileDir != null) {
                SSHTools ssh = new SSHTools(null, null);
                String runSiteName = Utils.getConfigurationValue(Constants.CFG_GRL_DEPLOY_NAME);
                String grIP = Utils.getGRHostIP(runSiteName);

                try {
                    String rs = ssh.cmd(grIP, "cd " + remotePackageFileDir + " && ls -lt SGR.export*.zip|head -1");
                    if (ssh.getExitStatusOfCommandResult(rs) != 0) {
                        logger.warn("get remote site replicator status failed, {}", ssh.getCommandErr(rs));
                    } else {
                        String str = ssh.getCommandOutput(rs);

                        String[] vars = str.split("\\s+");
                        ReplicatorStatusInfo remoteInfo = null;
                        if (vars.length > 8) {
                            remoteInfo = new ReplicatorStatusInfo();
                            remoteInfo.setCreatedTime(vars[5] + " " + vars[6] + " " + vars[7]);
                            remoteInfo.setFileName(remotePackageFileDir.endsWith("/") ? remotePackageFileDir + vars[8] : remotePackageFileDir + "/" + vars[8]);
                            remoteInfo.setFileSize(vars[4]);
                        } else {
                            if (logger.isTraceEnabled()){
                                logger.trace("ls latest file return illegal result: {}", str);
                            }
                        }
                        actionPlanOutputs.put(Constants.REPLICATOR_REMOTE_STATUS_INFO, remoteInfo);
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
    }
}
